package excel

import (
	"fmt"
	"unicode/utf8"

	"github.com/xuri/excelize/v2"
)

// ExcelWriter Excel 写入器
type ExcelWriter struct {
	file        *excelize.File
	fileName    string
	sheetRows   map[string]int // 记录各Sheet当前行号
	styles      map[string]int // 样式缓存
	activeSheet string
}

// EXCEL 列枚举
var EXCEL_ROW = []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AW", "AX", "AY", "AZ", "BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BK", "BL", "BM", "BN", "BO", "BP", "BQ", "BR", "BS", "BT", "BU", "BV", "BW", "BX", "BY", "BZ"}

// NewWriter 创建新的Excel写入器
func NewWriter() *ExcelWriter {
	f := excelize.NewFile()
	initialSheet := f.GetSheetName(0)

	return &ExcelWriter{
		file:        f,
		sheetRows:   map[string]int{initialSheet: 1},
		styles:      make(map[string]int),
		activeSheet: initialSheet,
	}
}

// SetFileName 设置保存文件名
func (ew *ExcelWriter) SetFileName(name string) *ExcelWriter {
	ew.fileName = name
	return ew
}

// SetSheet 设置/创建工作表
func (ew *ExcelWriter) SetSheet(sheetName string) *ExcelWriter {
	if _, exists := ew.sheetRows[sheetName]; !exists {
		index, _ := ew.file.NewSheet(sheetName)
		ew.sheetRows[sheetName] = 1
		ew.file.SetActiveSheet(index)
	}
	ew.activeSheet = sheetName
	return ew
}

// RegisterStyle 注册样式（支持缓存复用）
func (ew *ExcelWriter) RegisterStyle(styleKey string, style *excelize.Style) error {
	styleID, err := ew.file.NewStyle(style)
	if err != nil {
		return err
	}
	ew.styles[styleKey] = styleID
	return nil
}

// SetHeader 设置表头
func (ew *ExcelWriter) SetHeader(headers []interface{}, styleKeys ...string) error {
	currentRow := ew.sheetRows[ew.activeSheet]

	// 应用样式
	var styleID int
	if len(styleKeys) > 0 {
		if id, ok := ew.styles[styleKeys[0]]; ok {
			styleID = id
		}
	}

	for col, header := range headers {
		cell, _ := excelize.CoordinatesToCellName(col+1, currentRow)

		// 设置值
		if err := ew.file.SetCellValue(ew.activeSheet, cell, header); err != nil {
			return err
		}

		// 应用样式
		if styleID > 0 {
			if err := ew.file.SetCellStyle(ew.activeSheet, cell, cell, styleID); err != nil {
				return err
			}
		}
	}

	ew.sheetRows[ew.activeSheet] = currentRow + 1
	return nil
}

// AddRows 添加多行数据
func (ew *ExcelWriter) AddRows(data [][]interface{}, styleKeys ...string) error {
	for _, row := range data {
		if err := ew.AddRow(row, styleKeys...); err != nil {
			return err
		}
	}
	return nil
}

// AddRow 添加单行数据
func (ew *ExcelWriter) AddRow(data []interface{}, styleKeys ...string) error {
	currentRow := ew.sheetRows[ew.activeSheet]

	// 样式处理
	var styleIDs []int
	if len(styleKeys) > 0 {
		styleIDs = make([]int, len(data))
		for i, key := range styleKeys {
			if id, ok := ew.styles[key]; ok {
				styleIDs[i] = id
			}
		}
	}

	for col, value := range data {
		cell, _ := excelize.CoordinatesToCellName(col+1, currentRow)

		// 设置值
		if err := ew.file.SetCellValue(ew.activeSheet, cell, value); err != nil {
			return err
		}

		// 应用样式
		if len(styleIDs) > col && styleIDs[col] > 0 {
			if err := ew.file.SetCellStyle(ew.activeSheet, cell, cell, styleIDs[col]); err != nil {
				return err
			}
		}
	}

	ew.sheetRows[ew.activeSheet] = currentRow + 1
	return nil
}

// Save 保存文件
func (ew *ExcelWriter) Save() error {
	if ew.fileName == "" {
		return fmt.Errorf("文件名不能为空")
	}

	// 删除默认创建的空Sheet
	firstSheet := ew.file.GetSheetName(0)
	if firstSheet != ew.activeSheet {
		ew.file.DeleteSheet(firstSheet)
	}

	return ew.file.SaveAs(ew.fileName)
}

// MergeCells 合并单元格
func (ew *ExcelWriter) MergeCells(hCell, vCell string) error {
	return ew.file.MergeCell(ew.activeSheet, hCell, vCell)
}

// AutoColWidth 自动调整列宽
func (ew *ExcelWriter) AutoColWidth() error {
	cols, err := ew.file.GetCols(ew.activeSheet)
	if err != nil {
		return err
	}

	for idx, col := range cols {
		maxWidth := 0
		for _, rowCell := range col {
			cellWidth := utf8.RuneCountInString(rowCell) + 2
			if cellWidth > maxWidth {
				maxWidth = cellWidth
			}
		}
		ew.file.SetColWidth(ew.activeSheet, string(rune('A'+idx)), string(rune('A'+idx)), float64(maxWidth))
	}
	return nil
}

// FreezePane 冻结窗格
func (ew *ExcelWriter) FreezePane(topRow, leftCol int) error {
	panes := &excelize.Panes{
		Freeze:      true,
		Split:       false,
		XSplit:      leftCol,
		YSplit:      topRow,
		TopLeftCell: "A1",
		ActivePane:  "bottomRight",
	}
	return ew.file.SetPanes(ew.activeSheet, panes)
}

// GetCurrentRow 获取当前行
func (ew *ExcelWriter) GetCurrentRow() int {
	return ew.sheetRows[ew.activeSheet]
}

// SetCurrentRow 设置当前行
func (ew *ExcelWriter) SetCurrentRow(row int) {
	ew.sheetRows[ew.activeSheet] = row
}

// SetRowHeight 设置行高
func (ew *ExcelWriter) SetRowHeight(row int, height float64) error {
	return ew.file.SetRowHeight(ew.activeSheet, row, height)
}
